#ifndef AVALON_CONNECTIONGROUP_HPP
#define AVALON_CONNECTIONGROUP_HPP
#include <map>
#include <vector>
#include <boost/signals2.hpp>
#include "Avalon/SignalHandling/SignalHandling.hpp"

namespace Avalon {
namespace SignalHandling {

  /*! \class ConnectionGroup
   *  \brief Manages a group of connections.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class ConnectionGroup {
    public:

      //! Constructs a ConnectionGroup.
      ConnectionGroup();

      ~ConnectionGroup();

      //! Adds a connection to manage.
      /*!
        \param connection The connection to manage.
      */
      void AddConnection(const boost::signals2::connection& connection);

      //! Adds a SignalHandling::GroupConnection to manage.
      /*!
        \param connection The connection to manage.
      */
      void AddConnection(const SignalHandling::GroupConnection& connection);

      //! Adds a connection associated with a publisher.
      /*!
        \param publisher The publisher to associate the connection with.
        \param connection The connection to manage.
      */
      void AddConnection(void* publisher,
        const boost::signals2::connection& connection);

      //! Adds a SignalHandling::GroupConnection associated with a publisher.
      /*!
        \param publisher The publisher to associate the connection with.
        \param connection The connection to manage.
      */
      void AddConnection(void* publisher,
        const SignalHandling::GroupConnection& connection);

      //! Adds a connection associated with a publisher.
      /*!
        \param publisher The publisher to associate the connection with.
        \param connection The connection to manage.
      */
      template<typename T>
      void AddConnection(const boost::shared_ptr<T>& publisher,
          const boost::signals2::connection& connection) {
        AddConnection(publisher.get(), connection);
      }

      //! Adds a connection associated with a publisher.
      /*!
        \param publisher The publisher to associate the connection with.
        \param connection The connection to manage.
      */
      template<typename T>
      void AddConnection(const boost::scoped_ptr<T>& publisher,
          const boost::signals2::connection& connection) {
        AddConnection(publisher.get(), connection);
      }

      //! Disconnects all connections associated with a publisher.
      /*!
        \param publisher The publisher to disconnect all connections from.
      */
      void Disconnect(void* publisher);

      //! Disconnects all connections.
      void DisconnectAll();

    private:
      std::map<void*, std::vector<boost::signals2::scoped_connection*> >
        m_connections;
  };
}
}

#endif // AVALON_CONNECTIONGROUP_HPP
